﻿
using System.Diagnostics;
using MediatR;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Logging;
using ORS.OrderRobot.IOC;
using ORS.OrderRobot.Service.Helper;
using ORS.OrderRobot.Service.Jobs;
using ORS.OrderRobot.ServiceContracts;
using ORS.OrderRobot.ServiceContracts.ThridPartApi;

namespace ORS.OrderRobot.Service
{
    /// <summary>
    /// 商品探测任务
    /// </summary>
	public class ProductScanWorker : CronWorkerBase, IBackgroundWorker, IScoped
    {
        private readonly ISystemConfigService _systemConfigService;
        private readonly ILogger<ProductScanWorker> _logger;
        private readonly IMediator _mediator;
        private readonly IHubContext<MessageHub> _hubContext;
        private readonly IBackgroundJobManager _backgroundJobManager;
        private readonly LockCacheManager _lockCacheManager;
        private readonly IThirdProductService _thirdProductService;
        private readonly string _msgObj = "商品扫描器";
        public ProductScanWorker(
            ISystemConfigService systemConfigService,
            ILogger<ProductScanWorker> logger,
            IHubContext<MessageHub> hubContext,
            IBackgroundJobManager backgroundJobManager,
            LockCacheManager lockCacheManager,
            IMediator mediator,
            IThirdProductService thirdProductService
        )
        {
            _systemConfigService = systemConfigService;
            _logger = logger;
            _mediator = mediator;
            _hubContext = hubContext;
            _backgroundJobManager = backgroundJobManager;
            _lockCacheManager = lockCacheManager;
            _thirdProductService = thirdProductService;
        }

        public override string Name => nameof(ProductScanWorker);

        public override async Task<string> GetCronExpressionAsync()
        {
            var configDto = await _systemConfigService.GetConfigAsync();
            var task = configDto.MointerProductTask;
            var cron = CronHelper.GetCronByInterval(task.Interval, task.IntervalUnit);
            return cron;
        }

        protected override async Task DoWorkAsync()
        {
            var timeWatch = new Stopwatch();
            timeWatch.Start();
            try
            {
                var configDto = await _systemConfigService.GetConfigAsync();
                if (configDto.MointerProductTask.Disabled)
                {
                    _logger.LogWarning("商品扫描任务被禁用");
                    return;
                }
                var productList = configDto.MointerProductInfos;
                if (productList == null || !productList.Any())
                {
                    await MsgHelper.SendAsync(_hubContext, new MsgData { Obj = $"{_msgObj} ", Action = "未配置目标商品",Category="low" });
                    _logger.LogError("未配置扫描的商品组");
                    return;
                }
                await MsgHelper.SendAsync(_hubContext, new MsgData { Obj = $"{_msgObj} ", Action = "开始执行", Category = "low" });
                var taskLock = await _lockCacheManager.HasScanLock();
                if (taskLock)
                {
                    await MsgHelper.SendAsync(_hubContext, new MsgData { Obj = $"{_msgObj} ", Action = "上一轮任务还在执行", Category = "low" });
                    return;
                }
                await _lockCacheManager.SetScanLock();
                var tasks = productList.Select(async p =>
                {
                    var result = await _thirdProductService.ProductExists(p.Id);
                    if (result)
                    {
                        await MsgHelper.SendAsync(_hubContext, new MsgData { Obj = _msgObj, Action = $"{p.Name}上架了", Category = "low" });
                        if (configDto.MointerProductTask.AutoShopping)
                        {
                            await _mediator.Publish(new PurchaseEvent(p.Id, p.Name));
                        }
                        await _backgroundJobManager.EnqueueAsync<UpdateProductLogJob, UpdateProductLogArgs>(
                            new UpdateProductLogArgs
                            {
                                ProductId = p.Id,
                                ProductName = p.Name,
                                CreateTime = DateTime.Now.China()
                            }
                        );
                    }
                });
                await Task.WhenAll(tasks);
            }
            catch { }
            finally
            {
                _logger.LogInformation("ProductScanTasker-DoWorkAsync完成");
                timeWatch.Stop();
                await _lockCacheManager.RemoveScanLock();
                await MsgHelper.SendAsync(_hubContext, new MsgData { Obj = _msgObj, Action = "扫描完成", UsedTime = timeWatch.ElapsedMilliseconds, Category = "low" });
            }
        }

        protected override async Task<TimeOnly?[]> GetTimeRange()
        {
            var configDto = await _systemConfigService.GetConfigAsync();
            return new TimeOnly?[]
            {
                 configDto.MointerProductTask.StartTime,
                 configDto.MointerProductTask.EndTime,
            };
        }
    }
}

